package com.aacar.op.web.user;

import com.aacar.op.entity.user.User;
import com.aacar.op.service.user.IUserService;
import com.aacar.op.utils.Constant;
import com.aacar.op.utils.DateUtil;
import com.aacar.op.utils.enumeration.MenuPermissions;
import com.aacar.op.utils.pojo.ActionResult;
import com.aacar.op.utils.pojo.datatables.DataTablesResult;
import com.aacar.op.utils.web.PageUtils;
import com.aacar.op.utils.web.Servlets;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.Date;
import java.util.Map;


/**
 * 用户Controller
 */
@Controller
@RequestMapping("/op/user")
public class UserController {
    private static Logger logger = LoggerFactory.getLogger(UserController.class);

    @Autowired
    private IUserService userService;


    @RequestMapping(method = {RequestMethod.GET})
    public String list() {
        return "op/user/user";
    }


    /**
     * datatables json
     */
    @RequestMapping(value = "datatables", method = {RequestMethod.GET, RequestMethod.POST})
    public
    @ResponseBody
    DataTablesResult<User> datatables(HttpServletRequest request,
                                      @RequestParam(value = "search_startDate", required = false)
                                      @DateTimeFormat(pattern = Constant.DATE_PATTERN_SHORT) Date startDate,
                                      @RequestParam(value = "search_endDate", required = false)
                                      @DateTimeFormat(pattern = Constant.DATE_PATTERN_SHORT) Date endDate) {

        Pageable pageable = PageUtils.pageableFromDateTables(request);
        //使用Map传参到Service层,便于扩展.
        //获取"search_"的参数传as Map.
        Map<String, Object> params = Servlets.getParametersStartingWith(request, "search_");
        startDate = DateUtil.safeStartDate(startDate);
        endDate = DateUtil.safeEndDate(endDate);
        params.put("startDate", startDate);
        params.put("endDate", endDate);
        PageInfo<User> pageInfo = userService.getPage(params, pageable);
        return DataTablesResult.build(pageInfo);
    }

    /**
     * 编辑页面:: GET
     */
    @RequestMapping(value = "input", method = RequestMethod.GET)
    public String input(@ModelAttribute("entity") User entity, Model model) {
        model.addAttribute("menuPerSelect2JsonArr", MenuPermissions.asSelect2JsonArr());
        return "op/user/user-input";
    }

    /**
     * save or update :: POST
     */
    @RequestMapping(value = "input", method = RequestMethod.POST)
    public
    @ResponseBody
    ActionResult input(@Valid @ModelAttribute("entity") User entity, BindingResult result) {

        if (result.hasErrors()) {
            logger.warn(result.toString());
            return ActionResult.failure("数据不合法,保存失败。");
        }
        ActionResult actionResult;
        try {
            if (entity.isNew()) {
                userService.registerUser(entity);
            } else {
                userService.updateUser(entity);
            }
            actionResult = ActionResult.success("用户&quot;" + entity.getLoginName() + "&quot;保存成功。");
        } catch (Exception e) {
            logger.error("用户保存异常:{}", e);
            actionResult = ActionResult.failure("用户&quot;" + entity.getLoginName() + "&quot;保存失败。");
        }
        return actionResult;
    }

    /**
     * 删除 :: POST
     */
    @RequestMapping(value = "delete", method = RequestMethod.POST)
    public
    @ResponseBody
    ActionResult delete(@RequestParam Long deleteId) {

        ActionResult actionResult;
        try {
            userService.delete(deleteId);
            actionResult = ActionResult.success("删除成功。");
        } catch (Exception e) {
            logger.error("用户删除异常:{}", e);
            actionResult = ActionResult.failure("删除失败。");
        }
        return actionResult;
    }


    /**
     * 验证loginName是否可用
     *
     * @return JSON true || false
     */
    @RequestMapping(value = "validateLoginName", method = {RequestMethod.GET, RequestMethod.POST})
    public
    @ResponseBody
    Boolean validateLoginName(@RequestParam(value = "userId", required = false) Long id,
                              @RequestParam(value = "loginName", required = true) String loginName) {
        return userService.validateLoginName(id, loginName);
    }

    @RequestMapping(value = "validateMobile", method = {RequestMethod.GET, RequestMethod.POST})
    public
    @ResponseBody
    Boolean validateMobile(@RequestParam(value = "userId", required = false) Long id,
                           @RequestParam(value = "mobile", required = true) String mobile) {
        return userService.validateMobile(id, mobile);
    }

    @RequestMapping(value = "validateEmail", method = {RequestMethod.GET, RequestMethod.POST})
    public
    @ResponseBody
    Boolean validateEmail(@RequestParam(value = "userId", required = false) Long id,
                          @RequestParam(value = "email", required = true) String email) {
        return userService.validateEmail(id, email);
    }

    /**
     * AOP Preparable二次部分绑定的效果,类似Struts2 prepare 接口效果一样.
     */
    @ModelAttribute
    public void prepareModel(Model model, @RequestParam(value = "id", required = false) Long id) {
        if (id != null) {
            model.addAttribute("entity", userService.get(id));
        } else {
            model.addAttribute("entity", new User());
        }
    }

    /**
     * 不自动绑定对象中的属性
     */
    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        binder.setDisallowedFields("org");
        binder.setDisallowedFields("roles");
    }


}
